﻿' This file explains how you should use the Compiler tool to compile
' and solve expressions that have variables.
' Please NOTE that you don't need 2 sets of code to deal with expressions that have
' or have not variables. This code separation was made just for easier explanation and learning.

' 1. Add a reference to the Enhancements.Basic assembly.
' 2. Create an instance of the Enhancements.Basic.Expressions.Compiler class,
'    indicating which functions will be made available to the compiler.
' 3. Add an event handler to the compiler's ExpressionVariablesTypesRequest event.
'    If will be raised while compiling so that you can supply the variables types.
' 4. Call the compiler's Compile method in a try/catch block as the expression can be invalid.
'    If valid, an Expression instance is returned.
' 6. Before solving, provide each variable with it's intended value.
' 5. Call the Expression instance' Solve method in a try/catch block as the expression solving
'    can result in an exception. If all well, the expression's result is returned.

Imports Enhancements.Basic.Expressions

Public Class CompileAndSolveExpressionsWithVariables

    Private __Compiler As Compiler = Nothing

    Public Sub New()
        __Compiler = New Compiler(True, True, True, True, True, True, True, New Functions.Function() {})
        AddHandler __Compiler.ExpressionVariablesTypesRequest, AddressOf __ExpressionVariablesTypesRequest
    End Sub

    Private Sub __ExpressionVariablesTypesRequest(ByVal _sender As Object, ByVal _data As CompilerExpressionVariablesTypesRequestEventArgs)
        For Each _variable As CompilerExpressionVariablesTypesRequestEventArgsVariable In _data.Variables

            Dim _variableName As String = _variable.Name

            'Set each variable type by doing _variable.Type = xxx
            'xxx must be one of the types indicated by the Compiler.SupportedValuesTypes property

        Next _variable
    End Sub

    Public Function CompileAndSolve(ByVal _expressionText As String) As Object

        Dim _compiledExpression As Expression = Nothing
        Dim _expressionResult As Object = Nothing

        Try
            _compiledExpression = __Compiler.Compile(_expressionText)

        Catch _exception As Exception
            'The compilation process went wrong! Throw it back to the client.
            Throw New ApplicationException("Compilation generated an error.", _exception)
        End Try

        Try

            For Each _variable As ExpressionVariable In _compiledExpression.Variables

                Dim _variableName As String = _variable.Name
                Dim _variableTypeStatedPreviously As Type = _variable.Type
                Dim _variableTypeStatedPreviously_UnderlyingDotNetType As Type = _variable.UnderlyingType

                'Set each variable value by doing _variable.Value = xxx
                'xxx's type must conform to the type stated previously for the variable

            Next _variable

            _expressionResult = _compiledExpression.Solve()

        Catch _exception As Exception
            'The solving process went wrong! Throw it back to the client.
            Throw New ApplicationException("Solving generated an error.", _exception)
        End Try

        Return _expressionResult

    End Function

End Class
